package top.hmtools.mapper.plus;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.StringWriter;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import tk.mybatis.mapper.entity.EntityColumn;
import tk.mybatis.mapper.mapperhelper.EntityHelper;
import tk.mybatis.mapper.mapperhelper.MapperHelper;
import tk.mybatis.mapper.mapperhelper.MapperTemplate;

public abstract class BaseSqlProvider extends MapperTemplate{
	
	protected Logger logger = LoggerFactory.getLogger(this.getClass());

	public BaseSqlProvider(Class<?> mapperClass, MapperHelper mapperHelper) {
		super(mapperClass, mapperHelper);
	}

	/**
	 * 提取出用于生成SQL语句所需要的参数数据
	 * @param entityClass
	 * @return
	 */
	public Map<String,Object> getParams(Class<?> entityClass){
		Map<String,Object> params = new HashMap<>();
		
		//数据表名称
		String tableName = tableName(entityClass);
		params.put("tableName", tableName);
		
		//数据库表中字段名集合
		Set<EntityColumn> columnSet = EntityHelper.getColumns(entityClass);
		params.put("columns", columnSet);
		
		//获取所有该表的主键
        Set<EntityColumn> pkColumns = EntityHelper.getPKColumns(entityClass);
        params.put("pkColumns", pkColumns);
        
        //获取所有非主键字段名集合
        Set<EntityColumn> unPkColumns = new HashSet<>();
        unPkColumns.addAll(columnSet);
        unPkColumns.removeAll(pkColumns);
        params.put("unPkColumns", unPkColumns);
		
		return params;
	}
	
	/**
	 * 合成mybatis mapper.xml 中的SQL语句
	 * @param entityClass
	 * @param templatePath
	 * @return
	 */
	public String mergeToSQLstr(Class<?> entityClass, String templatePath){
		String result = null;
		//获取模板内容
		InputStream templateIS = Thread.currentThread().getContextClassLoader().getResourceAsStream("template/"+templatePath+".ftl");
		if(templateIS==null){
			throw new RuntimeException("获取SQL模板文件内容异常");
		}
		
		//获取数据模型
		Map<String, Object> params = this.getParams(entityClass);
		if(this.logger.isDebugEnabled()){
			this.logger.debug("所有参数：{}",params);
		}
		
		//初始化freemarker
		InputStreamReader isrContent = new InputStreamReader(templateIS);
	    Configuration cfg = new Configuration(Configuration.VERSION_2_3_22);
	    StringWriter stringWriter = new StringWriter();
	    Template temp = null;
		try {
			temp = new Template("mysql", isrContent,cfg);
			temp.process(params, stringWriter);
			result = stringWriter.toString();
			
			if(this.logger.isDebugEnabled()){
				this.logger.debug("模板路径：{}，合成后的SQL语句：{}",templatePath,result);
			}
		} catch (IOException | TemplateException e) {
			throw new RuntimeException("合成SQL语句异常", e);
		}
		return result;
	}
}
